package com.yangjun.common.excel;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;

import com.yangjun.utils.POIExcelUtils;
import com.yangjun.utils.ReflectUtil;

/**
 * 
 * @ClassName ExcelExport
 * @Description 导出实现类
 * @author Administrator
 * @Date 2017年6月23日 上午9:44:37
 * @version 1.0.0
 */
public class ExcelExport extends AbstractExcelResolver{

	public ExcelExport(ExcelDefinitionReader definitionReader) {
		super(definitionReader);
	}
	
	public ExcelExportResult createExcel(String id,List<?> beans,List<String> fields){
		ExcelExportResult excelExportResult = null;
		if(CollectionUtils.isNotEmpty(beans)){
			ExcelDefinition excelDefinition = definitionReader.getRegistry().get(id);
			if(excelDefinition==null){
				throw new ExcelException("没有找到 ["+id+"] 的配置信息");
			}
			Class<?> realClass = beans.get(0).getClass();
			if(realClass==excelDefinition.getClazz()){
				excelDefinition = dynamicCreateExcelDefinition(excelDefinition,fields);
			}
			excelExportResult = doCreateExcel(excelDefinition,beans);
		}
		return excelExportResult;
	}
	public ExcelExportResult createEmptyExcel(String id,Class<?> clazz,List<String> fields){
			ExcelDefinition excelDefinition = definitionReader.getRegistry().get(id);
			if(excelDefinition==null){
				throw new ExcelException("没有找到 ["+id+"] 的配置信息");
			}
			Class<?> realClass = clazz;
			if(realClass==excelDefinition.getClazz()){
				excelDefinition = dynamicCreateExcelDefinition(excelDefinition,fields);
			}
		return doCreateEmptyExcel(excelDefinition);
	}
	public Workbook createExcelTemplate(String id,List<String> fields){
		ExcelDefinition excelDefinition = definitionReader.getRegistry().get(id);
		if(excelDefinition==null){
			throw new ExcelException("没有找到 ["+id+"] 的配置信息");
		}
		excelDefinition = dynamicCreateExcelDefinition(excelDefinition, fields);
		return doCreateExcel(excelDefinition,null).build();
		
	}
	
	protected ExcelExportResult doCreateExcel(ExcelDefinition excelDefinition, List<?> beans){
		//创建workbook
		Workbook workbook = new SXSSFWorkbook();
		Sheet sheet = null;
		if(excelDefinition.getSheetname()!=null){
			sheet = workbook.createSheet(excelDefinition.getSheetname());
		}else{
			sheet = workbook.createSheet();
		}
		Row titleRow = createTitle(excelDefinition, sheet, workbook);
		if(beans!=null){
			createRows(excelDefinition, sheet, beans, workbook, titleRow);
		}
		ExcelExportResult exportResult = new ExcelExportResult(excelDefinition, sheet, workbook, titleRow,this);
		return exportResult;
	}
	protected ExcelExportResult doCreateEmptyExcel(ExcelDefinition excelDefinition){
		//创建workbook
		Workbook workbook = new SXSSFWorkbook();
		Sheet sheet = null;
		if(excelDefinition.getSheetname()!=null){
			sheet = workbook.createSheet(excelDefinition.getSheetname());
		}else{
			sheet = workbook.createSheet();
		}
		Row titleRow = createTitle(excelDefinition, sheet, workbook);
		ExcelExportResult exportResult = new ExcelExportResult(excelDefinition, sheet, workbook, titleRow,this);
		return exportResult;
	}
	/**
	 * @Description 创建行
	 * @param excelDefinition
	 * @param sheet
	 * @param beans
	 * @param workbook
	 * @param titleRow
	 * @author yangjun
	 * @Date 2017年6月23日 上午11:30:37
	 */
	protected void createRows(ExcelDefinition excelDefinition,Sheet sheet,List<?> beans,Workbook workbook,Row titleRow){
		int num = sheet.getPhysicalNumberOfRows();
		int startRow = num;
		for(int i=0;i<beans.size();i++){
			Row row = sheet.createRow(i+num);
			createRow(excelDefinition,row,beans.get(i),workbook,sheet,titleRow,startRow++);
		}
	}
	
	protected void createRow(ExcelDefinition excelDefinition,Row row,Object bean,Workbook workbook,Sheet sheet,Row titleRow,int rowNum){
		List<FieldValue> fieldValues = excelDefinition.getFieldValues();
		for (int i=0;i<fieldValues.size();i++){
			FieldValue fieldValue = fieldValues.get(i);
			String name = fieldValue.getName();
			Object value = ReflectUtil.getProperty(bean, name);
			Object val = null;
			try {
				val = convert(bean, value, fieldValue, Type.EXPORT,rowNum);
			} catch (Exception e) {
				e.printStackTrace();
			}
			Cell cell = row.createCell(i);
			setCellValue(cell, val);
		}
	}
	
	protected Row createTitle(ExcelDefinition excelDefinition,Sheet sheet,Workbook workbook){
		//标题索引号
		int titleIndex = sheet.getPhysicalNumberOfRows();
		Row titleRow = sheet.createRow(titleIndex);
		List<FieldValue> fieldValues = excelDefinition.getFieldValues();
		for(int i = 0; i<fieldValues.size();i++){
			FieldValue fieldValue = fieldValues.get(i);
			//设置单元格宽度
			if(fieldValue.getColumnWidth() !=null){
				sheet.setColumnWidth(i, fieldValue.getColumnWidth());
			}//如果默认的宽度不为空,使用默认的宽度
			else if(excelDefinition.getDefaultColumnWidth()!=null){
				sheet.setColumnWidth(i, excelDefinition.getDefaultColumnWidth());
			}
			Cell cell = titleRow.createCell(i);
			if(excelDefinition.getEnableStyle()){
				if(fieldValue.getAlign()!=null || fieldValue.getTitleBgColor()!=null || fieldValue.getTitleFountColor() !=null || excelDefinition.getDefaultAlign()!=null){
					cell.setCellStyle(workbook.createCellStyle());
					//设置cell 对齐方式
					setAlignStyle(fieldValue, workbook, cell,excelDefinition);
					//设置标题背景色
					setTitleBgColorStyle(fieldValue, workbook, cell);
					//设置标题字体色
					setTitleFountColorStyle(fieldValue, workbook, cell);
				}
			}
			setCellValue(cell,fieldValue.getTitle());
		}
		return titleRow;
	}
	/**
	 * 设置Cell单元的值
	 * 
	 * @param cell
	 * @param value
	 */
	protected void setCellValue(Cell cell, Object value) {
		POIExcelUtils.setCellValue(cell, value);
	}
	//设置cell 对齐方式
	private void setAlignStyle(FieldValue fieldValue,Workbook workbook,Cell cell,ExcelDefinition excelDefinition){
		if(fieldValue.getAlign()!=null){
			CellStyle cellStyle = cell.getCellStyle();
			cellStyle.setAlignment(HorizontalAlignment.CENTER);
			cell.setCellStyle(cellStyle);
		}else if(excelDefinition.getDefaultAlign()!=null){
			CellStyle cellStyle = cell.getCellStyle();
			cellStyle.setAlignment(HorizontalAlignment.CENTER);
			cell.setCellStyle(cellStyle);
		}
	}
	
	//设置cell 背景色方式
	private void setTitleBgColorStyle(FieldValue fieldValue,Workbook workbook,Cell cell){
		if(fieldValue.getTitleBgColor()!=null){
			CellStyle cellStyle = cell.getCellStyle();
			cellStyle.setFillForegroundColor(fieldValue.getTitleBgColor());
			cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
		}
	}
	
	//设置cell 字体颜色
	private void setTitleFountColorStyle(FieldValue fieldValue,Workbook workbook,Cell cell){
		if(fieldValue.getTitleFountColor()!=null){
			CellStyle cellStyle = cell.getCellStyle();
			Font font = workbook.createFont();
			font.setColor(fieldValue.getTitleFountColor());
			cellStyle.setFont(font);
		}
	}
	private ExcelDefinition dynamicCreateExcelDefinition(ExcelDefinition excelDefinition,List<String> fields){
		if(CollectionUtils.isNotEmpty(fields)){
			ExcelDefinition newDef = new ExcelDefinition();
			ReflectUtil.copyProps(excelDefinition, newDef,"fieldValues");
			List<FieldValue> oldValues = excelDefinition.getFieldValues();
			List<FieldValue> newValues = new ArrayList<FieldValue>(oldValues.size());
			//按照顺序,进行添加
			for(String name:fields){
				for(FieldValue field:oldValues){
					String fieldName = field.getName();
					if(fieldName.equals(name)){
						newValues.add(field);
						break;
					}
				}
			}
			newDef.setFieldValues(newValues);
			return newDef;
		}
		return excelDefinition;
	}
}
